package com.audi.core.dao;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.Criterion;

import com.audi.core.common.Page;
import com.audi.core.dao.PropertyFilter.MatchType;

  
public interface BaseDAO<T, PK extends Serializable> extends SimpleDAO<T, PK>{
	
	/* (non-Javadoc)
	 * @see com.sitech.core.orm.hibernate.S22#getAll(com.sitech.core.orm.Page)
	 */
	public abstract Page<T> getAll(final Page<T> page);

	/**
	 * 按HQL分页查询.
	 * 
	 * @param page 分页参数. 注意不支持其中的orderBy参数.
	 * @param hql hql语句.
	 * @param values 数量可变的查询参数,按顺序绑定.
	 * 
	 * @return 分页查询结果, 附带结果列表及所有查询输入参数.
	 */
	
	
	/**
	 * 按HQL分页查询.
	 * 
	 * @param page 分页参数. 注意不支持其中的orderBy参数.
	 * @param hql hql语句.
	 * 无占位符及参数，如 hql = "from S s where t.status=1"
	 * 
	 * @return 分页查询结果, 附带结果列表及所有查询输入参数.
	 */
	public abstract Page<T> findPage(final Page<T> page, final String hql);
	
	
	public abstract Page<T> findPage(final Page<T> page, final String hql,
			final Object... values);

	/**
	 * 按HQL分页查询.
	 * 
	 * @param page 分页参数. 注意不支持其中的orderBy参数.
	 * @param hql hql语句.
	 * @param values 命名参数,按名称绑定.
	 * 
	 * @return 分页查询结果, 附带结果列表及所有查询输入参数.
	 */
	public abstract Page<T> findPage(final Page<T> page, final String hql,
			final Map<String, ?> values);

	/* (non-Javadoc)
	 * @see com.sitech.core.orm.hibernate.S22#findPage(com.sitech.core.orm.Page, org.hibernate.criterion.Criterion)
	 */
	
	public abstract Page<T> findPage(final Page<T> page,
			final Criterion... criterions);

	/**
	 * 设置分页参数到Query对象,辅助函数.
	 */
	public abstract Query setPageParameterToQuery(final Query q,
			final Page<T> page);

	/**
	 * 设置分页参数到Criteria对象,辅助函数.
	 */
	public abstract Criteria setPageParameterToCriteria(final Criteria c,
			final Page<T> page);

	/**
	 * 执行count查询获得本次Hql查询所能获得的对象总数.
	 * 
	 * 本函数只能自动处理简单的hql语句,复杂的hql查询请另行编写count语句查询.
	 */
	public abstract long countHqlResult(final String hql,
			final Object... values);

	/**
	 * 执行count查询获得本次Hql查询所能获得的对象总数.
	 * 
	 * 本函数只能自动处理简单的hql语句,复杂的hql查询请另行编写count语句查询.
	 */
	public abstract long countHqlResult(final String hql,
			final Map<String, ?> values);

	/**
	 * 执行count查询获得本次Criteria查询所能获得的对象总数.
	 */
	
	public abstract long countCriteriaResult(final Criteria c);

	/**
	 * 按属性查找对象列表,支持多种匹配方式.
	 * 
	 * @param matchType 匹配方式,目前支持的取值见PropertyFilter的MatcheType enum.
	 */
	public abstract List<T> findBy(final String propertyName,
			final Object value, final MatchType matchType);

	/**
	 * 按属性过滤条件列表查找对象列表.
	 */
	public abstract List<T> find(List<PropertyFilter> filters);

	/**
	 * 按属性过滤条件列表分页查找对象.
	 */
	public abstract Page<T> findPage(final Page<T> page,
			final List<PropertyFilter> filters);

	
	public Criterion buildCriterion(final String propertyName, final Object propertyValue, final MatchType matchType);
	
	/**
	 * 按属性条件列表创建Criterion数组,辅助函数.
	 */
	public abstract Criterion[] buildCriterionByPropertyFilter(
			final List<PropertyFilter> filters);

	/**
     * 原生sql支持
     * @param sql
     * @param cacheable
     * @return
     */
    public List executeList(String sql, boolean cacheable);
    
    /**
     * 原生sql支持带参数
     * @param sqlstr
     * @param params
     * @param cacheable
     * @return
     */
    public List executeListByCondition(String sqlstr, Object[] params, boolean cacheable);
    
    /**
     * 原生sql支持带参数及分页
     * @param begin
     * @param pageSize
     * @param sqlstr
     * @param params
     * @param cacheable
     * @return
     */
    public List executeListByCondition(int begin, int pageSize, String sqlstr, final Object[] params, boolean cacheable);
    
    
    public Page executePage(Page page, String sql, boolean cacheable);
     
    public Page executePage(int begin, int pageSize, String sqlstr, final Object[] params, boolean cacheable);
     
    public Page executePage(Page page, String sqlstr, final Object[] params, boolean cacheable);
    
    
    /**
     * 
     * @param pageNo 页码
     * @param pageSize 页大小
     * @param hql ?号占位符hql
     * @param arr 参数
     * @return
     */
    public Page<T> findByProperty(int pageNo, int pageSize, String hql, Object[] arr);
    
    
	
}